package com.jandan.persistence.sqlmapdao;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.jandan.persistence.iface.WordDao;
import com.jandan.ui.client.util.ClientUtil;
import com.jandan.ui.model.CnAndSentence;
import com.jandan.ui.model.Word;

/**
 * WordDao接口实现类，使用Ibatis框架进行持久化
 * @author Gong Yong
 * @version 1.0
 * @see com.jandan.persistence.iface.WordDao
 */
public class WordSqlMapDao extends SqlMapClientDaoSupport implements WordDao {
	public Word getWordByWordID(long wordID) {
		// TODO Auto-generated method stub
		Word w = (Word) this.getSqlMapClientTemplate().queryForObject(
				"Word.getWordByWordID", Long.valueOf(wordID));

		w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
		return w;
	}

	public Word getWordByWordEn(String wordEn) {
		// TODO Auto-generated method stub
		List<Word> wordList = (List<Word>) this.getSqlMapClientTemplate()
				.queryForList("Word.getWordByWordEn", wordEn, 0, 1);
		if (wordList != null && wordList.size() > 0) {
			Word w = wordList.get(0);
			w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
			return w;
		}
		return null;
	}

	public Word getWordOfOnePositionByWordLibID(long wordLibID, int position) {
		// TODO Auto-generated method stub
		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getWordListByWordLibID", wordLibID, position, 1);
		if (wordList != null && wordList.size() > 0) {
			Word w = wordList.get(0);
			if (w != null) {
				w
						.setCnAndSentenceList(this.getCnAndSentenceList(w
								.getWordID()));
				return w;
			}
		}
		return null;
	}

	public Word getStrangeWordOfOnePositionByUserID(long userID, int position) {
		// TODO Auto-generated method stub
		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getStrangeWordListByUserID", userID, position, 1);
		if (wordList != null && wordList.size() > 0) {
			Word w = wordList.get(0);
			if (w != null) {
				w
						.setCnAndSentenceList(this.getCnAndSentenceList(w
								.getWordID()));
				return w;
			}
		}
		return null;
	}

	public List<Word> getNewWordListByWordLibID(long lessonID, long wordLibID,
			int offset, int limit) {
		// TODO Auto-generated method stub
		Map map = new HashMap();
		map.put("wordLibID", wordLibID);
		map.put("lessonID", lessonID);
		map.put("offset", offset);
		map.put("limit", limit);

		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getNewWordListByWordLibID", map);
		Word w = null;
		for (Iterator<Word> it = wordList.iterator(); it.hasNext();) {
			w = it.next();
			w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
		}
		return wordList;
	}

	public List<Word> getWordListByWordLibID(long wordLibID) {
		// TODO Auto-generated method stub
		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getWordListByWordLibID", Long.valueOf(wordLibID));
		Word w = null;
		for (Iterator<Word> it = wordList.iterator(); it.hasNext();) {
			w = it.next();
			w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
		}
		return wordList;
	}

	public List<Word> getWordListByWordLibID(long wordLibID, int offset,
			int limit) {
		// TODO Auto-generated method stub
		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getWordListByWordLibID", Long.valueOf(wordLibID), offset,
				limit);
		Word w = null;
		for (Iterator<Word> it = wordList.iterator(); it.hasNext();) {
			w = it.next();
			w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
		}
		return wordList;
	}

	public int getTotalWordCountOfWordLib(long wordLibID) {
		// TODO Auto-generated method stub
		return (Integer) this.getSqlMapClientTemplate().queryForObject(
				"Word.getWordsCountOfWordLib", Long.valueOf(wordLibID));
	}

	public long insertWord(Word word) {
		// TODO Auto-generated method stub
		long wordID = 0;
		try {
			this.getSqlMapClient().startTransaction();
			this.getSqlMapClientTemplate().insert("Word.insertWord", word);
			wordID = (Long) getSqlMapClientTemplate().queryForObject(
					"Word.lastInsertWordID");
			List<CnAndSentence> cnAndSentenceList = word.getCnAndSentenceList();
			CnAndSentence cs = null;
			if (cnAndSentenceList != null) {
				for (int i = 0; i < cnAndSentenceList.size(); i++) {
					cs = cnAndSentenceList.get(i);
					cs.setWordID(wordID);
					this.getSqlMapClientTemplate().insert(
							"Word.insertCnAndSentence", cs);
				}
			}

			this.getSqlMapClient().commitTransaction();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				this.getSqlMapClient().endTransaction();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return wordID;
	}

	public void updateWord(Word word) {
		// TODO Auto-generated method stub
		List<CnAndSentence> csList = word.getCnAndSentenceList();
		CnAndSentence cs = null;
		for (Iterator<CnAndSentence> it = csList.iterator(); it.hasNext();) {
			cs = it.next();
			if (cs.getCsID() > 0) {
				this.getSqlMapClientTemplate().update(
						"Word.updateCnAndSentence", cs);
			} else {
				this.getSqlMapClientTemplate().insert(
						"Word.insertCnAndSentence", cs);
			}
		}

		this.getSqlMapClientTemplate().update("Word.updateWord", word);
	}

	public void deleteWord(long wordID) {
		// TODO Auto-generated method stub
		this.getSqlMapClientTemplate().delete("Word.deleteWord", wordID);
	}

	public List<Word> getStrangeWordListByUserID(long userID) {
		// TODO Auto-generated method stub
		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getStrangeWordListByUserID", userID);
		Word w = null;
		for (Iterator<Word> it = wordList.iterator(); it.hasNext();) {
			w = it.next();
			w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
		}
		return wordList;
	}

	public List<Word> getStrangeWordListByUserID(long userID, int offset,
			int limit) {
		// TODO Auto-generated method stub
		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getStrangeWordListByUserID", userID, offset, limit);
		Word w = null;
		for (Iterator<Word> it = wordList.iterator(); it.hasNext();) {
			w = it.next();
			w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
		}
		return wordList;
	}

	public List<Word> getNewStrangeWordListByUserID(long userID, int offset,
			int limit) {
		// TODO Auto-generated method stub
		Map map = new HashMap();
		map.put("userID", userID);
		map.put("lessonID", ClientUtil.STRANGE_LESSON_ID);
		map.put("offset", offset);
		map.put("limit", limit);
		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getNewStrangeWordListByUserID", map);
		Word w = null;
		for (Iterator<Word> it = wordList.iterator(); it.hasNext();) {
			w = it.next();
			w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
		}
		return wordList;
	}

	public int getStrangeWordCountByUserID(long userID) {
		// TODO Auto-generated method stub
		return (Integer) this.getSqlMapClientTemplate().queryForObject(
				"Word.getStrangeWordCountByUserID", userID);
	}

	public Word getStrangeWordByWordEn(String wordEn, long userID) {
		Map map = new HashMap();
		map.put("wordEn", wordEn);
		map.put("userID", userID);
		map.put("wordLibID", ClientUtil.STRANGE_WORDLIB_ID);

		List<Word> wordList = (List<Word>) this.getSqlMapClientTemplate()
				.queryForList("Word.getStrangeWordByWordEn", map, 0, 1);
		Word w = null;
		if (wordList != null && wordList.size() > 0) {
			w = wordList.get(0);
			if (w != null) {
				w
						.setCnAndSentenceList(this.getCnAndSentenceList(w
								.getWordID()));
				return w;
			}
		}
		return null;
	}

	public void insertStrangeWord(Word word, long userID) {
		// TODO Auto-generated method stub
		Word w = this.getStrangeWordByWordEn(word.getWordEn(), userID);
		if (w != null) {
			// this.deleteWord(w.getWordID());
			return;
		}

		word.setWordLibID(ClientUtil.STRANGE_WORDLIB_ID);

		long strangeWordID = this.insertWord(word);
		Map<String, Long> map = new HashMap<String, Long>();

		map.put("wordID", strangeWordID);
		map.put("userID", userID);

		this.getSqlMapClientTemplate().insert("Word.insertStrangeWordRelation",
				map);
	}

	public int getSearchedWordCount(String word, long wordLibID) {
		// TODO Auto-generated method stub
		Map map = generateSearchWordMap(word, wordLibID);

		return (Integer) this.getSqlMapClientTemplate().queryForObject(
				"Word.getSearchedWordCount", map);
	}

	public List<Word> getSearchedWordList(String word, int offset, int limit,
			long wordLibID) {
		// TODO Auto-generated method stub
//		Map map = generateSearchWordMap(word, wordLibID);

		List<Word> wordList = this.getSqlMapClientTemplate().queryForList(
				"Word.getSearchedWordList", word + "%", offset, limit);
		Word w = null;
		for (Iterator<Word> it = wordList.iterator(); it.hasNext();) {
			w = it.next();
			w.setCnAndSentenceList(this.getCnAndSentenceList(w.getWordID()));
		}
		return wordList;
	}

	private Map generateSearchWordMap(String word, long wordLibID) {
		// TODO Auto-generated method stub
		Map map = new HashMap();
		map.put("word", word + "%");
		map.put("wordLibID", wordLibID);

		return map;
	}

	private List<CnAndSentence> getCnAndSentenceList(long wordID) {
		return this.getSqlMapClientTemplate().queryForList(
				"Word.getCnAndSentenceListByWordID", wordID);
	}

	public void deleteCnAndSentence(long csID) {
		// TODO Auto-generated method stub
		this.getSqlMapClientTemplate().delete("Word.deleteCnAndSentence", csID);
	}

	public Word getWordByWordEnAndWordLibID(String wordEn, long wordLibID) {
		// TODO Auto-generated method stub
		Map map = new HashMap();
		map.put("wordEn", wordEn);
		map.put("wordLibID", wordLibID);
		Word word = (Word) this.getSqlMapClientTemplate().queryForObject(
				"Word.getWordByWordEnAndWordLibID", map);
		if (word != null) {
			word.setCnAndSentenceList(this.getCnAndSentenceList(word
					.getWordID()));
		}
		return word;
	}
}
